package ru.spbau.design.snmp.android.viewer.view;

import ru.spbau.design.snmp.android.viewer.R;
import ru.spbau.design.snmp.android.viewer.model.Router;
import ru.spbau.design.snmp.android.viewer.model.SubNet;
import ru.spbau.design.snmp.android.viewer.searcher.SearchResult;
import ru.spbau.design.snmp.android.viewer.searcher.SearcherSimple;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ExpandableListView;

class SearchTab {
	static final int G_SUBNETS = 0;
	static final int G_ROUTERS = 1;
	static final int G_NODES = 2;
	
	ViewerActivity.Accessor accessor;
	
	ExpandableListView searchResultView;
	EditText queryEdit;
	
	SearcherSimple searcher;
	SearchResult searchResult;
	
	SearchResultAdapter searchResultAdapter;
	
	SearchQueryListener searchQueryListener;
	SearchResultClickListener searchViewClickListener;
	
		
	public SearchTab(ViewerActivity.Accessor accessor) {
		this.accessor = accessor;
		
		this.searcher = new SearcherSimple();
		this.searchQueryListener = new SearchQueryListener();
		this.searchViewClickListener = new SearchResultClickListener();
		this.searchResultAdapter = new SearchResultAdapter();
		
		this.searchResultView = (ExpandableListView) accessor.context().findViewById(R.id.searchResultListView);
		this.searchResultView.setOnChildClickListener(this.searchViewClickListener);
		this.searchResultView.setAdapter(this.searchResultAdapter);
		
		this.queryEdit = (EditText) accessor.context().findViewById(R.id.queryEdit);		
		this.queryEdit.setOnKeyListener(this.searchQueryListener);
	}
	
	
	private void updateSearchResults(String query) {
		if (query.length() == 0) {
			return;
		}
	
		this.searchResult = this.searcher.search(query, accessor.snapshot());
		
		for (int i = 0; i < this.searchResultAdapter.getGroupCount(); ++i) {
			this.searchResultView.collapseGroup(i);
		}
		this.searchResultView.invalidateViews();
	}
	
	// --------------------------------------------------------------------------------

	private class SearchResultAdapter extends AdapterBase {
		final String[] groups = { "Subnets", "Routers", "Nodes" };

		public SearchResultAdapter() { }

		public int getGroupCount() {
			return groups.length;
		}

		public int getChildrenCount(int groupPosition) {
			if (searchResult == null) {
				return 0;
			}
			
			int v = 0;

			switch (groupPosition) {
			case G_SUBNETS:
				v = searchResult.getSubNetworks().size();
				break;

			case G_ROUTERS:
				v = searchResult.getRouters().size();
				break;

			case G_NODES:
				v = searchResult.getNetNodes().size();
				break;
			}

			/*
			System.out.println("Returning children count for the group "
					+ Integer.toString(groupPosition) + " ("
					+ Integer.toString(v) + ")");
					*/

			return v;
		}

		public long getCombinedChildId(long groupId, long childId) {
			return groupId * groups.length + childId + 1;
		}

		public long getCombinedGroupId(long groupId) {
			return groupId * groups.length;
		}

		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			System.out.println("Getting a view for the group "
					+ Integer.toString(groupPosition));

			TextView tv = (TextView) convertView;
			if (tv == null) {
				System.out.println("Creating a new group view");

				tv = new TextView(accessor.context());
			}

			tv.setMinHeight(50);
			tv.setGravity(android.view.Gravity.CENTER_VERTICAL);
			tv.setText(groups[groupPosition]);
			return tv;
		}

		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			/*
			System.out.println("Getting view for the group "
					+ Integer.toString(groupPosition) + " and the child "
					+ Integer.toString(childPosition));
					*/

			TextView tv = (TextView) convertView;
			if (tv == null) {
				tv = new TextView(accessor.context());
			}

			try {
				switch (groupPosition) {
				case G_SUBNETS:
					tv.setText(searchResult.getSubNetworks().get(childPosition).getId());
					break;

				case G_ROUTERS:
					tv.setText(searchResult.getRouters().get(childPosition).getDescription());
					break;

				case G_NODES:
					tv.setText(searchResult.getNetNodes().get(childPosition).getName());
					break;
				}
			} catch (Exception e) {
				System.out.println("Failed to setup the view for the group "
						+ Integer.toString(groupPosition) + " and the child "
						+ Integer.toString(childPosition));

				tv.setText("<Invalid>");
			}

			return tv;
		}

		public boolean isEmpty() {
			return false;
		}
	}

	// --------------------------------------------------------------------------------

	private class SearchQueryListener implements TextView.OnKeyListener {
		public SearchQueryListener() { }

		public boolean onKey(View v, int keyCode, KeyEvent event) {
			if (event.getAction() == KeyEvent.ACTION_UP
					&& keyCode == KeyEvent.KEYCODE_ENTER) {
				//System.out.println("Submitting the query...");

				updateSearchResults(queryEdit.getEditableText().toString());
				return true;
			}

			return false;
		}
	}

	// --------------------------------------------------------------------------------

	private class SearchResultClickListener implements
			ExpandableListView.OnChildClickListener {

		public SearchResultClickListener() { }

		public boolean onChildClick(ExpandableListView parent, View v,
				int groupPos, int childPos, long id) {

			Rev pos;
			int g;

			switch (groupPos) {
			case G_SUBNETS:
				SubNet subnet = searchResult.getSubNetworks().get(childPos);
				g = accessor.getSubnetPos(subnet);

				accessor.subnetsView().setSelectedGroup(g);
				accessor.tabs().setCurrentTabByTag("Subnets");
				break;

			case G_ROUTERS:
				Router router = searchResult.getRouters().get(childPos);
				g = accessor.getRouterPos(router);

				accessor.routersView().setSelectedGroup(g);
				accessor.routersView().expandGroup(g);
				accessor.tabs().setCurrentTabByTag("Routers");
				break;

			case G_NODES:
				pos = accessor.getSubnetPos(searchResult.getNetNodes().get(childPos));
				accessor.subnetsView().setSelectedChild(pos.getGroup(), pos.getChild(), true);
				accessor.tabs().setCurrentTabByTag("Subnets");
				break;
			}

			return false;
		}
	}

}
